package com.example.stgv;

import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Color;
import android.net.Uri;
import android.provider.CalendarContract;
import android.provider.CalendarContract.Calendars;
import android.text.format.Time;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class CalendarView extends LinearLayout implements OnClickListener,
		OnItemClickListener {

	/**
	 * ********************************************* utility part
	 */
//	private static final String DATE_TIME_FORMAT = "yyyy MMM dd, HH:mm:ss";
	final String[] l_projection = new String[] { Calendars._ID, // 0
			Calendars.ACCOUNT_NAME, // 1
			Calendars.CALENDAR_DISPLAY_NAME }; // 2
	private GridView mGrid;
	private View mConvertView;
	private GregorianCalendar mCalendar;
	private Date[] mWeek;
	private Context mContext;
	private TextView mMonthText;
	private SimpleDateFormat mFormatDay, mFormatMonth,mFormatYear;
	private OnDispatchDateSelectListener mListenerDateSelect;
	private Button mArrowRight,mArrowLeft;
	private CalendarAdapter mAdapter;

	public CalendarView(Context context, AttributeSet attrs) {
		super(context, attrs);
		mContext = context;
		mFormatMonth = new SimpleDateFormat("MMMM",java.util.Locale.getDefault());
		mFormatDay = new SimpleDateFormat("d",java.util.Locale.getDefault());
		mFormatYear = new SimpleDateFormat("yyyy",java.util.Locale.getDefault());

		mConvertView = LayoutInflater.from(context).inflate(
				R.layout.activity_calendar_view, this);
		mGrid = (GridView) mConvertView.findViewById(R.id.calendar_days);

		mGrid.setOnItemClickListener(this);

		mMonthText = (TextView) mConvertView.findViewById(R.id.calendar_month);
		mArrowLeft = (Button) findViewById(R.id.calendar_arrow_left);
		mArrowLeft.setOnClickListener(this);

		mArrowRight = (Button) mConvertView
				.findViewById(R.id.calendar_arrow_right);
		mArrowRight.setOnClickListener(this);

		mCalendar = (GregorianCalendar) GregorianCalendar.getInstance();
		mCalendar.setTime(new Date());

		// mCalendar.add(Calendar.DAY_OF_YEAR, -7);
		mCalendar.add(Calendar.DAY_OF_WEEK, mCalendar.getFirstDayOfWeek()
				- mCalendar.get(Calendar.DAY_OF_WEEK));
		mWeek = new Date[7];
		for (int i = 0; i <7 ; i++) {
			mWeek[i] = mCalendar.getTime();
			mCalendar.add(Calendar.DAY_OF_YEAR, 1);
		}
		setSelectedMonthText();
		mAdapter = new CalendarAdapter(mContext, mWeek);
		mGrid.setAdapter(mAdapter);
	}

	public static String getDateTimeStr(String p_time_in_millis) {
		SimpleDateFormat sdf = new SimpleDateFormat("HH:mm",java.util.Locale.getDefault());
		//SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy, HH:mm:sz",java.util.Locale.getDefault());
		Date l_time = new Date(Long.parseLong(p_time_in_millis));
		return sdf.format(l_time);
	}

	@Override
	public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {
		clearBackground();
		v.setBackgroundColor(Color.parseColor("#3A9CE9"));
		mListenerDateSelect.onDispatchDateSelect(mWeek[arg2]);
	}
	@Override
	public void onClick(View v) {
		int id = v.getId();
		if (id == R.id.calendar_arrow_left) {
			subWeek();
		} else if (id == R.id.calendar_arrow_right) {
			addWeek();
		}
	}

	// ==============================================================

	private void addWeek() {
		for (int i = 0; i < 7; i++) {
			mWeek[i] = mCalendar.getTime();
			mCalendar.add(Calendar.DAY_OF_YEAR, 1);
		}

		mAdapter.notifyDataSetChanged();

		setSelectedMonthText();
		clearBackground();
	}

	private void subWeek() {
		mCalendar.add(Calendar.DAY_OF_YEAR, -14);
		for (int i = 0; i < 7; i++) {
			mWeek[i] = mCalendar.getTime();
			mCalendar.add(Calendar.DAY_OF_YEAR, 1);
		}
		setSelectedMonthText();
		mAdapter.notifyDataSetChanged();

		clearBackground();
	}

	private void clearBackground() {
		for (int i = 0; i < mGrid.getCount(); i++) {
			mGrid.getChildAt(i).setBackgroundColor(Color.TRANSPARENT);
		}
	}

	private void setSelectedMonthText() {
		String monthText;
		if (Integer.parseInt(mFormatDay.format(mWeek[0])) > Integer
				.parseInt(mFormatDay.format(mWeek[6])))
			monthText = mFormatMonth.format(mWeek[0]) + " / "
					+ mFormatMonth.format(mWeek[6]);
		else
			monthText = mFormatMonth.format(mWeek[0]);

		mMonthText.setText(monthText + " " + mFormatYear.format(mWeek[6]));

	}

	public void setOnDispatchDateSelectListener(OnDispatchDateSelectListener v) {
		mListenerDateSelect = v;

	}

	public interface OnDispatchDateSelectListener {
		public void onDispatchDateSelect(Date date);
	}

	public static ArrayList<String> getEvents(Context mContext,Date now) {
		ArrayList<String> arrEvent = new ArrayList<String>();
		
		Time dayStart = new Time();
	    dayStart.set(now.getTime());
	    dayStart.hour=0;
	    dayStart.minute=0;
	    dayStart.second=0;

	    Time dayEnd = new Time();
	    dayEnd.set(dayStart);
	    dayEnd.hour=dayStart.hour+23;
	    dayEnd.minute=dayStart.minute+59;
	    dayEnd.second=dayStart.second+59;

	    Long dayStartInMillis = dayStart.toMillis(false);
	    Long dayEndInMillis = dayEnd.toMillis(false) + 999;
	    
		Log.d("Thong Bao", "Today la " + now +" - " + dayStartInMillis + " - " + dayEndInMillis );

		Uri.Builder eventsUriBuilder = CalendarContract.Instances.CONTENT_URI
				.buildUpon();
		ContentUris.appendId(eventsUriBuilder, dayStartInMillis);
		ContentUris.appendId(eventsUriBuilder, dayEndInMillis);
		Uri eventsUri = eventsUriBuilder.build();

/*		String selection = CalendarContract.Events.DTSTART + " >= ? AND "
				+ CalendarContract.Events.DTSTART + "<= ?";*/
		
		String selection = CalendarContract.Instances.START_DAY + " >= ? AND "
				+ CalendarContract.Instances.START_DAY + "<= ?";
		String[] selectionArgs = new String[] { Long.toString(dayStartInMillis),
				Long.toString(dayEndInMillis) };

		String[] l_projection = new String[] {
				CalendarContract.Instances.CALENDAR_ID,// 0
				CalendarContract.Instances.EVENT_ID, // 1
				CalendarContract.Instances.TITLE, // 2
				CalendarContract.Instances.EVENT_LOCATION, // 3
				CalendarContract.Instances.DESCRIPTION,// 4
				CalendarContract.Instances.START_DAY,// 5
				CalendarContract.Instances.BEGIN,// 6
				CalendarContract.Instances.START_MINUTE,// 7
				CalendarContract.Instances.END_DAY, // 8
				CalendarContract.Instances.END_MINUTE,// 9
				CalendarContract.Instances.END }; // 10

		String sorting = CalendarContract.Instances.START_DAY + " ASC, "
				+ CalendarContract.Instances.START_MINUTE + " ASC";

		try {
/*			Cursor cursor = mContext.getContentResolver().query(eventsUri,
					l_projection, selection, selectionArgs, sorting);*/
			Cursor cursor = mContext.getContentResolver().query(eventsUri,
					l_projection, null, null, sorting);


			Log.d("Thong Bao", "So record " + cursor.getCount());
			String l_title = "null", l_begin = "null", l_end = "null", l_local;
			while (cursor != null && cursor.moveToNext()) {
				for (int i = 0; i < 11; i++) {
					Log.d("Thong Bao",
							l_projection[i] + " " + cursor.getString(i));
				}
				Log.d("Thong Bao", "------------------------------------- ");

				l_title = cursor.getString(2);
				l_begin = getDateTimeStr(cursor.getString(6));
				l_end = getDateTimeStr(cursor.getString(10));
				l_local = cursor.getString(3);

				arrEvent.add(l_title + "\n" + l_begin + "\n" + l_end + "\n" + l_local);
			}
			cursor.close();
		} catch (Exception e) {
			e.printStackTrace();
			Log.d("Thong Bao", "Lỗi không truy vấn được Event. ");
		}
		return arrEvent;

	}
}